/******************************************************************************
 * Copyright 2007 - 2021 Realtek Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/
 
#include "rtw_wlan_config.h"
#include "harmony_types.h"
#include "osdep_service.h"

extern int rtw_wconfig_handler (void *dev, void *command);

static int wlan_config_ioctl(void *ip_ptr, void *iw_cmd)
{
	return rtw_wconfig_handler(ip_ptr, iw_cmd);
}


/*
 * Description
 *      Start BSS Scan
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_scan(void *devptr,void *scan_req)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_SCAN;
    iw_cmd.iwcp.wc_apps_data = scan_req;

    return wlan_config_ioctl(devptr, &iw_cmd);
}
int rtw_wc_abort_scan(void *devptr)
{
	struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_ABORT_SCAN;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_site_survey(void *devptr, rtw_wc_bss_info *results, int max_bss)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_EXT_SCAN;
    iw_cmd.iwcp.wc_apps_data = results;
    iw_cmd.iwcp.param1 = max_bss;
    iw_cmd.iwcp.param2 = 0;
    if (wlan_config_ioctl(devptr, &iw_cmd) == WC_STATUS_ERROR) {
        return WC_STATUS_ERROR;
    }
    return iw_cmd.iwcp.param2;
}

int rtw_wc_set_pmkid(void *devptr, void *pmkid)
{
	struct rtw_wc_command iw_cmd;
	int retval = 0;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_PMKID;
	iw_cmd.iwcp.wc_apps_data = pmkid;

	retval = wlan_config_ioctl(devptr, &iw_cmd);
	return retval;
}


/*
 * Description
 *		Set Driver operating mode
 * Arguments
 *		devptr			TCP/IP Stack specific network device pointer
 *		mode			Select between Staion/IBSS/SoftAP modes
 * Returns
 *		0 on success and a negative error code on failure
 */
int rtw_wc_set_mode(void *devptr, unsigned int mode)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_MODE;
	iw_cmd.iwcp.param1 = mode;

	return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_get_mode(void *devptr, unsigned int *mode)
{
	struct rtw_wc_command iw_cmd;
	int retval;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_GET_MODE;
	if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
		*mode = iw_cmd.iwcp.param1;
	}

	return retval;
}
/*
 * Description
 *		Set Network BSSID
 * Arguments
 *		devptr			TCP/IP Stack specific network device pointer
 *		bssid			BSSID of the network to join
 * Returns
 *		0 on success and a negative error code on failure
 */
int rtw_wc_set_bssid(void *devptr, char *bssid)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_BSSID;
	iw_cmd.iwcp.wc_apps_data = (void *)bssid;

	return wlan_config_ioctl(devptr, &iw_cmd);
}

/*
 * Description
 *		Set ESSID / Network name
 * Arguments
 *		devptr			TCP/IP Stack specific network device pointer
 *		essid			ESSID of the network to join
 *		essidlen		Length of the ESSID mentioned above.
 * Returns
 *		0 on success and a negative error code on failure
 */
int rtw_wc_set_essid(void *devptr, char *essid, unsigned int ssidlen)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_ESSID;
	iw_cmd.iwcp.wc_apps_data = (void *)essid;
	iw_cmd.iwcp.param1 = ssidlen;

	return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_set_auth(void *devptr,int flags,unsigned int value)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_AUTH;
	iw_cmd.iwcp.param1 = flags;
	iw_cmd.iwcp.param2 = value;


	return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_get_mac(void *devptr, char *bssid)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_GET_MAC;
	iw_cmd.iwcp.wc_apps_data = (void *)bssid;

	return wlan_config_ioctl(devptr, &iw_cmd);
}

/*
 * Description
 *      Get current BSSID joined/started
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      bssid           BSSID of the network
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_get_bssid(void *devptr, char *bssid)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_BSSID;
    iw_cmd.iwcp.wc_apps_data = (void *)bssid;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

/*
 * Description
 *      Get ESSID / Network name
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      essid           ESSID of the joined network
 *      ssidlen         Returned Length of the ESSID mentioned above.
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_get_essid(void *devptr, char *essid, unsigned int *ssidlen)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_ESSID;
    iw_cmd.iwcp.wc_apps_data = (void *)essid;
    iw_cmd.iwcp.param1 = WC_ESSID_MAX_SIZE;

    retval = wlan_config_ioctl(devptr, &iw_cmd);
    if (retval == WC_STATUS_SUCCESS) {
        *ssidlen = iw_cmd.iwcp.param1;
    }

    return retval;
}

int rtw_wc_set_genie(void *devptr, char *ie, unsigned int ie_len)
{

    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_GEN_IE;
    iw_cmd.iwcp.wc_apps_data = ie;
    iw_cmd.iwcp.param1 = ie_len;

    retval = wlan_config_ioctl(devptr, &iw_cmd);
    return retval;
}

/*
 * Description
 *      Set WEP Configuration data
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      key             64/128 bit Encryption Key
 *      keylen          Key length
 *      index           WEP Key index
 *      flags           Flags to specify Transmit Key index
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_wep_config(void *devptr, char *key, int keylen, int index,
        unsigned int flags)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_WEP_CONFIG;

    /* Set the key first */
    iw_cmd.iwcp.wc_apps_data = (void *)key;
    iw_cmd.iwcp.param1 = keylen;
    iw_cmd.iwcp.param2 = flags;
    iw_cmd.iwcp.param3 = index;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_wep_config(void *devptr, char *key, int *keylen, int *index,
        unsigned int *flags)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_WEP_CONFIG;
    iw_cmd.iwcp.wc_apps_data = (void*) key;
    iw_cmd.iwcp.param1 = 0;

    retval = wlan_config_ioctl(devptr, &iw_cmd);
    if (retval == WC_STATUS_SUCCESS) {
        *keylen = iw_cmd.iwcp.param1;
        *index  = iw_cmd.iwcp.param3;
    }
    *flags  = iw_cmd.iwcp.param2;

    return retval;
}


int rtw_wc_get_auth(void *devptr,unsigned int *authmode)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_AUTH;
    retval  = wlan_config_ioctl(devptr, &iw_cmd);
    if (retval == WC_STATUS_SUCCESS) {
         *authmode  = iw_cmd.iwcp.param1;
    }

    return retval;
}

int rtw_wc_set_encodeext(void *devptr, void *ext,int index, int flags)
{
	struct rtw_wc_command iw_cmd;

	_rtw_memset(&iw_cmd,0,sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_ENCODE_EXT;
	iw_cmd.iwcp.param1 = index;
	iw_cmd.iwcp.wc_apps_data = ext;
	iw_cmd.iwcp.param2 = flags;

	return  wlan_config_ioctl(devptr, &iw_cmd);
}

/*
 * Description
 *      Set Operating Channel
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      freq            Wireless Channel number
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_freq(void *devptr, unsigned int flags,unsigned int freq)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_FREQ;
    iw_cmd.iwcp.param1 = freq;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_freq(void *devptr, unsigned int *freq)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_FREQ;

    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *freq = iw_cmd.iwcp.param1;
    }

    return retval;
}

int rtw_wc_channel_list(void *devptr, unsigned int is_5g,unsigned int *n_channel,struct rtk_channel_info* channel_list)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_CHANNRL_LIST;
	iw_cmd.iwcp.param1 = is_5g;
	iw_cmd.iwcp.wc_apps_data = (void*)channel_list;

    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *n_channel = iw_cmd.iwcp.param2;
		
    }

    return retval;

}

/*
 * Description
 *      Set Transmit Data rate
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      rate            Transmit data rate in bits per second
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_rate(void *devptr, unsigned int rate)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_RATE;
    iw_cmd.iwcp.param1 = rate;
 
    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_rate(void *devptr, unsigned int *rate)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_RATE;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *rate = iw_cmd.iwcp.param1;
    }

    return retval;
}
int rtw_wc_support_rate(void *devptr,unsigned int *n_rate, unsigned char *rate)
{
	struct rtw_wc_command iw_cmd;
	int retval;
	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SUPPORT_RATE;
	iw_cmd.iwcp.wc_apps_data = (void*) rate;
	
	if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
		*n_rate = iw_cmd.iwcp.param1;
	}

	return retval;

}

/*
 * Description
 *      Set RTS Threshold
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      rts_t           RTS Threshold value
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_rts(void *devptr, unsigned int rts_t)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_RTS_THRES;
    iw_cmd.iwcp.param1 = rts_t;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_rts(void *devptr, unsigned int *rts_t)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_RTS_THRES;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *rts_t = iw_cmd.iwcp.param1;
    }
    return retval;
}


/*
 * Description
 *      Set Fragmentation Threshold
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      frag            Fragmentation threshold value
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_frag(void *devptr, unsigned int frag)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_FRAG_THRES;
    iw_cmd.iwcp.param1 = frag;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_frag(void *devptr, unsigned int *frag_t)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_FRAG_THRES;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *frag_t = iw_cmd.iwcp.param1;
    }
    return retval;
}


/*
 * Description
 *      Set Transmit Power
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      pow_dbm         Transmit power in dBm
 *      pow_flags       Flags to indiate Auto/Fixed Tx power
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_txpow(void *devptr, int pow_dbm)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_TXPOW;
    iw_cmd.iwcp.param1 = pow_dbm;
    //iw_cmd.iwcp.param2 = pow_flags;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


/*
 * Description
 *      Get current radio transmit power
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      pow_dbm         Pointer to store transmit power
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_get_txpow(void *devptr, int *pow_dbm)
{
    int retval;
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_TXPOW;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *pow_dbm = (int)iw_cmd.iwcp.param1;
    }

    return retval;
}



/*
 * Description
 *      Get BSS Scan results
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      callback        Callback handler for each BSS entry
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_get_scan(void *devptr, rtw_wc_scan_cb callback)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));

    /* The callback function is passed in "buf" member */
    iw_cmd.wc_cmd = RTW_WC_GET_SCAN;
    iw_cmd.iwcp.wc_apps_data = (void *)callback;
	if (wlan_config_ioctl(devptr, &iw_cmd) == WC_STATUS_ERROR) {
		return WC_STATUS_ERROR;
    }
	return iw_cmd.iwcp.param2;
}


int rtw_wc_get_scan_ie(void *devptr, rtw_wc_user_event_cb callback)
{
    struct rtw_wc_command iw_cmd;

    memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_SCAN_IE;
    iw_cmd.iwcp.wc_apps_data = (void *)callback;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_get_wireless_stats(void *devptr, unsigned char *lq,
        unsigned char *rssi, unsigned char *nl)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));

    /* The callback function is passed in "buf" member */
    iw_cmd.wc_cmd = RTW_WC_GET_WIRELESS_STATS;
    wlan_config_ioctl(devptr, &iw_cmd);
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *lq   = iw_cmd.iwcp.param1;
        *rssi = iw_cmd.iwcp.param2;
        *nl   = iw_cmd.iwcp.param3;
    }

    return retval;
}


/*
 * Description
 *      Set Power save mode
 * Arguments
 *      devptr          TCP/IP Stack specific network device pointer
 *      psmode          Power save mode
 * Returns
 *      0 on success and a negative error code on failure
 */
int rtw_wc_set_psmode(void *devptr, unsigned int psmode)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_PS_MODE;
    iw_cmd.iwcp.param1 = psmode;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_psmode(void *devptr, unsigned int *psmode)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_PS_MODE;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *psmode = iw_cmd.iwcp.param1;
    }

    return retval;
}


int rtw_wc_set_addr(void *devptr, u8*addr, u8 len)
{
	struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_WRITE_ADDR;
	iw_cmd.iwcp.wc_apps_data = (void*)addr;
	iw_cmd.iwcp.param1 = len;
	
    return  wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_add_key(void *devptr, u8 keyIndex, bool pairwise, const u8 *macAddr,struct Key_Params *params)
{
	struct rtw_wc_command iw_cmd;
    int retval;
	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_ADD_KEY;
	iw_cmd.iwcp.wc_apps_data = (void*)macAddr;
	iw_cmd.iwcp.param1 = keyIndex;
	iw_cmd.iwcp.param2 = pairwise;
	iw_cmd.iwcp.wc_apps_data1 = (void*)params;
	return	wlan_config_ioctl(devptr, &iw_cmd);

}

int rtw_wc_default_key(void *devptr, u8 keyIndex, bool unicast, bool multicas)
{
	struct rtw_wc_command iw_cmd;
    int retval;
	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_DEFAULT_KEY;
	iw_cmd.iwcp.param1 = keyIndex;
	iw_cmd.iwcp.param2 = unicast;
	iw_cmd.iwcp.param3 = multicas;

	return  wlan_config_ioctl(devptr, &iw_cmd);
}
int rtw_wc_del_key(void *devptr, u8 keyIndex, bool pairwise, const u8 *addr)
{
	struct rtw_wc_command iw_cmd;
	int retval;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_DEL_KEY;
	iw_cmd.iwcp.wc_apps_data = (void*)addr;
	iw_cmd.iwcp.param1 = keyIndex;
	iw_cmd.iwcp.param2 = pairwise;
	
	return	wlan_config_ioctl(devptr, &iw_cmd);

}

int rtw_wc_set_retry_limit(void *devptr, int retry_limit)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_RETRY_LIMIT;
    iw_cmd.iwcp.param1 = (unsigned int)retry_limit;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_retry_limit(void *devptr, int *retry_limit)
{
    struct rtw_wc_command iw_cmd;
    int retval;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_RETRY_LIMIT;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *retry_limit = iw_cmd.iwcp.param1;
    }

    return retval;
}

int rtw_wc_set_mac(void *devptr, char *bssid)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_MAC;
    iw_cmd.iwcp.wc_apps_data = (void *)bssid;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_set_deauth(void *devptr, unsigned char *mac_addr, unsigned int reason)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_DEAUTH;
    if (mac_addr && reason) {
        iw_cmd.iwcp.wc_apps_data = mac_addr;
        iw_cmd.iwcp.param1 = reason;
    }

    return wlan_config_ioctl(devptr, &iw_cmd);
}

/*
 * condition : 1 WPS Start 
 *           : 2 WPS Stop because of WPS Success 
 *           : 3 WPS Stop beacuse of WPS Fail
 */ 

int rtw_wc_wps_enable_session(void *devptr, int enable)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_WPS_SESSION;
    iw_cmd.iwcp.param1 = (unsigned int)enable;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

#ifdef ANTCFG_SUPPORT
int rtw_wc_get_antcfg(void *devptr, int *txpath, int *rxpath)
{
    struct rtw_wc_command iw_cmd;
    int retvalue;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_SET_ANTCFG;
    iw_cmd.iwcp.param1 = 0;

    retvalue = wlan_config_ioctl(devptr, &iw_cmd);
    if (retvalue == WC_STATUS_SUCCESS) {
        *txpath = iw_cmd.iwcp.param2;
        *rxpath = iw_cmd.iwcp.param3;
    }

    return retvalue;
}


int rtw_wc_set_antcfg(void *devptr, int txpath, int rxpath)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_SET_ANTCFG;
    iw_cmd.iwcp.param1 = 1;
    iw_cmd.iwcp.param2 = txpath;
    iw_cmd.iwcp.param3 = rxpath;

    return wlan_config_ioctl(devptr, &iw_cmd);
}
#endif


int rtw_wc_set_multicast_mode(void *devptr, int flags)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_MULTICAST_MODE;
    iw_cmd.iwcp.param1 = (unsigned int)flags;
    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_set_band(void *devptr, rtw_wc_wlan_band band)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_SET_BAND;
    iw_cmd.iwcp.param1 = 1;     /* Set Data */
    iw_cmd.iwcp.param2 = (unsigned int)band;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_band(void *devptr, unsigned int *band)
{
    struct rtw_wc_command iw_cmd;
    int retvalue;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_SET_BAND;
    iw_cmd.iwcp.param1 = 0;     /* Get Data */
    if ((retvalue = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *band = iw_cmd.iwcp.param2;
    }

    return retvalue;
}


int rtw_wc_set_connection_cb(void *devptr, rtw_wc_user_event_cb wcevent_cb)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_CONN_CB;
    iw_cmd.iwcp.wc_apps_data = (void *)wcevent_cb;

    return wlan_config_ioctl(devptr, &iw_cmd);
}

int rtw_wc_set_region_code(void *devptr, unsigned char* region,int len)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_REGION_CODE;
    iw_cmd.iwcp.param1 = len;
	iw_cmd.iwcp.wc_apps_data=region;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


int rtw_wc_get_region_code(void *devptr, unsigned int *region)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_REGION_CODE;
    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *region = iw_cmd.iwcp.param1;
    }

    return retval;
}


int rtw_wc_set_priv(void *devptr,unsigned char *ies, int len, int magic)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_PRIVATE;
    iw_cmd.iwcp.wc_apps_data = (void *)ies;
    iw_cmd.iwcp.param1 = len;
    iw_cmd.iwcp.param2 = magic;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
};

int rtw_wc_set_commit(void *devptr)
{
	return 0;
}

int rtw_wc_set_mlme(void *devptr, int cmd, int reason_code, unsigned char *addr)
{

    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_MLME;
    iw_cmd.iwcp.wc_apps_data = addr;
    iw_cmd.iwcp.param1 = reason_code;
    iw_cmd.iwcp.param2 = cmd;

    retval = wlan_config_ioctl(devptr, &iw_cmd);
    return retval;
}

int rtw_wc_set_write32(void *devptr, unsigned int bytes, 
                   unsigned int data32, unsigned int addr)
{
   struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_WRITE32;
    iw_cmd.iwcp.param1 = bytes;
    iw_cmd.iwcp.param2 = data32;
    iw_cmd.iwcp.param3  = addr;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_get_read32(void *devptr, unsigned int bytes,
                 unsigned int addr,unsigned int *data32)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_READ32;
    iw_cmd.iwcp.param1 = bytes;
    iw_cmd.iwcp.param2 = addr;

    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *data32 = iw_cmd.iwcp.param3;
    }

    return retval;
}

int rtw_wc_set_write_rf(void *devptr, unsigned int path, unsigned int addr,
                    unsigned int data32)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_RF;
    iw_cmd.iwcp.param1 = path;
    iw_cmd.iwcp.param2 = addr;
    iw_cmd.iwcp.param3 = data32;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_get_read_rf(void *devptr, unsigned int path,
                 unsigned int addr,unsigned int *data32)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_RF;
    iw_cmd.iwcp.param1 = path;
    iw_cmd.iwcp.param2 = addr;

    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *data32 = iw_cmd.iwcp.param3;
    }

    return retval;
}

int rtw_wc_set_channel_plan(void *devptr, unsigned char channel_plan)
{

    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_CHAN_PLAN;
    iw_cmd.iwcp.param1 = (unsigned int) channel_plan;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_get_ap_info(void *devptr, void *buf, int length, char *out)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_GET_AP_INFO;
    iw_cmd.iwcp.param1 = length;
    iw_cmd.iwcp.wc_apps_data = buf ;

    if ((retval = wlan_config_ioctl(devptr, &iw_cmd)) == WC_STATUS_SUCCESS) {
        *out = iw_cmd.iwcp.param2;
    }

    return retval;
}

int rtw_wc_set_pid(void *devptr, void *buf)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_PID;
    iw_cmd.iwcp.wc_apps_data = buf;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_hostapd_set_encryption(void *devptr, void *param, int len)
{
    struct rtw_wc_command iw_cmd;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_HOSTAPD_SETKEY;
    iw_cmd.iwcp.param1 = len;
    iw_cmd.iwcp.wc_apps_data = param;

    return wlan_config_ioctl(devptr, &iw_cmd);
}


/* 
 * Arguments : val32 decodes the argument/major_cmd/minor_cmd
 *             extra_arg - for write
 */

int rtw_wc_rtw_dbg_port(void *devptr, unsigned int val32, unsigned int extra_arg)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_SET_DBG_PORT;
    iw_cmd.iwcp.param1 = val32;
    iw_cmd.iwcp.param2 = extra_arg;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_set_ap(void *devptr, unsigned char *pbuf, unsigned int length)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_SET_AP;
    iw_cmd.iwcp.wc_apps_data = pbuf;
    iw_cmd.iwcp.param1 = length;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_set_ap_config(void *devptr, struct rtk_APConf * apconf)
{
	struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_SET_AP_CONFIG;
    iw_cmd.iwcp.wc_apps_data = (void *)apconf;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}
int rtw_wc_set_ap_beacon(void *devptr, struct rtk_BeaconConf * beaconconf)
{
	struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_SET_AP_BEACON;
    iw_cmd.iwcp.wc_apps_data = (void *)beaconconf;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;

}

int rtw_wc_set_ap_start(void *devptr)
{
	struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_SET_AP_START;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;

}


int rtw_wc_ap_get_sta_num(void *devptr, unsigned char* sta_num)
{
	struct rtw_wc_command iw_cmd;
	int retval = 0;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_HAPD_GET_STA_NUM;
    iw_cmd.iwcp.wc_apps_data = sta_num;
    
	retval = wlan_config_ioctl(devptr, &iw_cmd);

	return retval;
}



int rtw_wc_ap_get_sta_list(void *devptr, struct rtk_WifiStaInfo *staInfo,unsigned char sta_num)
{
	struct rtw_wc_command iw_cmd;
	int retval = 0;
	
	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_HAPD_GET_STA_LIST;
    iw_cmd.iwcp.wc_apps_data = (void *)staInfo;
	iw_cmd.iwcp.param1 = sta_num;
    
	retval = wlan_config_ioctl(devptr, &iw_cmd);

	return retval;
}


int rtw_wc_get_ap_new_sta_wpa_ie(void *devptr, unsigned char *sta_addr,unsigned char *piebuf, unsigned int *length)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_GET_NEW_STA_WPA_IE;
    iw_cmd.iwcp.wc_apps_cb = sta_addr;
    iw_cmd.iwcp.wc_apps_data = piebuf;
    iw_cmd.iwcp.param1 = 32;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

   if(retval == WC_STATUS_SUCCESS)
   	*length = iw_cmd.iwcp.param1;

    return retval;
}

int rtw_wc_ap_sta_flush(void *devptr)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_STA_FLUSH;

    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_set_remove_sta(void *devptr, unsigned char *sta_addr)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_STA_REMOVE;
    iw_cmd.iwcp.wc_apps_data = sta_addr;
    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_ap_set_bcn_ie(void *devptr, unsigned char *ie,unsigned int len)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_WPS_SET_BCN_IE;
    iw_cmd.iwcp.wc_apps_data = ie;
	iw_cmd.iwcp.param1 = len;
    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_ap_set_probe_resp_ie(void *devptr, unsigned char *ie,unsigned int len)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_WPS_SET_PROBE_RESP_IE;
    iw_cmd.iwcp.wc_apps_data = ie;
	iw_cmd.iwcp.param1 = len;
    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

int rtw_wc_ap_set_assoc_resp_ie(void *devptr, unsigned char *ie,unsigned int len)
{
    struct rtw_wc_command iw_cmd;
    int retval = 0;

    _rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
    iw_cmd.wc_cmd = RTW_WC_HAPD_WPS_SET_ASSOC_RESP_IE;
    iw_cmd.iwcp.wc_apps_data = ie;
	iw_cmd.iwcp.param1 = len;
    retval = wlan_config_ioctl(devptr, &iw_cmd);

    return retval;
}

#ifdef CONFIG_MP_INCLUDED
int rtw_wc_mp_set(void *devptr, unsigned char cmd, unsigned char*data, unsigned int len)
{
	struct rtw_wc_command iw_cmd;
	int retval = 0;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_SET_MP;
	iw_cmd.iwcp.wc_apps_data = data;
	iw_cmd.iwcp.param1 = cmd;
	iw_cmd.iwcp.param2 = len;
	retval = wlan_config_ioctl(devptr, &iw_cmd);

	return retval;
}

int rtw_wc_mp_get(void *devptr, unsigned char cmd, unsigned char*data, unsigned int len)
{
	struct rtw_wc_command iw_cmd;
	int retval = 0;

	_rtw_memset(&iw_cmd, 0, sizeof(struct rtw_wc_command));
	iw_cmd.wc_cmd = RTW_WC_GET_MP;
	iw_cmd.iwcp.wc_apps_data = data;
	iw_cmd.iwcp.param1 = cmd;
	iw_cmd.iwcp.param2 = len;
	retval = wlan_config_ioctl(devptr, &iw_cmd);

	return retval;
}

#endif

